use std::collections::HashMap;
use std::io;
use std::io::Read;
use std::fs::File;

fn main() {
    println!("Hello, world!");
    
    let mut mem = Members{
        id :1405546456544553,
        name :String::from("rust"),
        age :23,
        grade :8,
    };
    println!("name = {}", mem.get_name());
    println!("age = {}", mem.set_age(33));
    
    println!("sub = {}", Members::sub(3,9));
    
    println!("grade = {}", mem.add_grade());
    
    
    let mut us = Users{
        id :1405546456544559,
        name :String::from("golang"),
        age :17,
        grade :6,
    };
    
    println!("out_put_grade = {}", output(mem));
    println!("out_put_grade = {}", output(us));
    
    println!("member.grade = {}", get_member("c++".to_string(), 37, 2).get_grade());
    
    let mut v2 :Vec<i64> = Vec::new();
    let mut v1 = vec![1,5,7];
    let mut v :Vec<i64> = vec![3,74,8];
    v.push(1646);
    v.push(6646);
    v.push(6456);
    v.push(9772);
    v1.append(&mut v);
    println!("v = {:?}", v);
    println!("v1[2] = {:?}", v1[2]);
    println!("v1 = {:?}", v1);
    
    match v1.get(3){
        Some(d) =>{
            println!("v1[3] = {:?}", d);
        },
        None =>{
            println!("None");
        }
    }
    
    if let Some(m) = v1.get(3){
        println!("v1[3] = {:?}", m);
    }else{
        {
            println!("None");
        }
    }
    
    let y :u64 = 999;
    match nesting_error_hadler(y){
        Ok(n) => println!("nesting_error_hadler = {}", n),
        Err(e) => println!("error = {}", e),
    }
    
    for value in &v1{
        println!("value = {}", value);
    }
    
    // let mut r :usize = 0;
    // loop{
    //     if r > v1.len(){
    //         break;
    //     }
    //     println!("v1{} = {}", r, v1[r]);
    //     r += 1;
    // }
    
    for j in &mut v1{
        *j += 10
    }
    println!("v1 = {:?}", v1);
    
    let one = 1.to_string();
    println!("one = {}", one);
    
    let f = 35.777.to_string();
    println!("f = {}", f);
    
    let mut p :String = String::from("rust actix-web");
    p.push_str(" 牛逼");
    println!("p = {}", p);
    p.push('!');
    println!("p = {}", p);
    
    let rocket = String::from(" go fiber 不行");
    let l = p + &rocket;
    println!("l = {}", l);
    
    println!("pc = {:?}", l.chars());
    
    for x in l.chars(){
        println!("x = {}", x);
    }
    
    println!("pslice = {:?}", &[0..4]);
    
    let mut map1 :HashMap<String, u64> = HashMap::new();
    let mut map = HashMap::new();
    map.insert("rust".to_string(), 10);
    map.insert("golang".to_string(), 7);
    map.insert("c++".to_string(), 13);
    map.insert("python3".to_string(), 3);
    println!("map = {:?}", map);
    
    println!("map_get = {}", map.get("golang").unwrap());
    
    for (j,z) in map.iter(){
        println!("j = {}, z = {}", j, z);
    }
    
    match map.get_mut("java"){
        Some(j) =>{
            println!("j = {}", j);
        },
        None =>{
            println!(" None Erroe");
        }
    }
    
    if let Some(s) = map.get_mut("python3"){
        println!("s = {}", s);
    }else{
        println!(" None Erroe");
    }
    
    let list :[char; 5] = ['#', '*', '&', '!', '$'];
    for t in &list[0..3]{
        println!("t = {}", t);
    }
    
    match read_file("hello_rust.txt"){
        Ok(s) =>{
            println!("s = {}", s);
        },
        Err(e) =>{
            match e.kind(){
                io::ErrorKind::NotFound =>{
                    println!("not find file");
                },
                _ =>{
                    println!("Cannot read the file");
                }
            }
        }
    }
    
    let mut ms :String = String::new();
    ms.push_str("docker ");
    ms.push_str("spring cloud alibaba");
    println!("ms = {:?}", ms);
    
    if let Ok(s) = return_ok("iris".to_string()){
        println!("s = {}", s);
    }else{
        println!("error");
    }
    
    println!("subtb = {}", subtb(100, 300))
}

#[derive(Debug)]
struct Members{
    id :u64,
    name :String,
    age :u8,
    grade :u8,
}

#[derive(Debug)]
struct Users{
    id :u64,
    name :String,
    age :u8,
    grade :u8,
}

trait Member_interface{
    fn add_grade(&mut self) ->String;
    
    fn get_grade(&self) ->u8;
}

impl Members{
    fn get_name(&self) ->&String{
        &self.name
    }
    
    fn set_age(&mut self, a :u8) ->u8{
        self.age = a;
        
        self.age
    }
    
    fn sub(a :u8, g :u8) ->u8{
        a*g
    }
}

impl Member_interface for Members{
    fn add_grade(&mut self) ->String{
        self.grade += 1;
        
        format!("{}", self.grade)
    }
    
    fn get_grade(&self) ->u8{
        self.grade
    }
}

impl Member_interface for Users{
    fn add_grade(&mut self) ->String{
        self.grade += 1;
        
        format!("{}", self.grade)
    }
    
    fn get_grade(&self) ->u8{
        self.grade
    }
}

fn output(mut object :impl Member_interface) ->String{
    object.add_grade()
}

fn get_member(name :String, age :u8, t :u8) ->impl Member_interface{

    // if t == 1{
    //     Members{
    //         id :1405546456544554,
    //         name :name,
    //         age :age,
    //         grade :5,
    //     }
    // }else{
       Users{
            id :1405546456544555,
            name :name,
            age :age,
            grade :1,
        } 
    // }
}

fn error_hadler(y :u64) ->Result<u64, bool>{
    if y > 999{
        Ok(y)
    }else{
        Err(false)
    }
}

fn nesting_error_hadler(y :u64) ->Result<u64, bool>{
    match error_hadler(y){
        Ok(u) =>{
            Ok(u)
        },
        Err(e) =>{
            Err(e)
        }
    }
}

fn return_ok(s :String) ->Result<String, bool>{
    Ok(s)
}

fn read_file(path :&str) ->Result<String, io::Error>{
    let mut f = File::open(path)?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    
    Ok(s)
}

fn subtb(t :i64, d :i64) ->i64{
    t*d
}
